package org.mindrive.system.web.system;

import org.mindrive.system.collection.system.UserEntity;
import org.mindrive.system.core.Result;
import org.mindrive.system.parameter.BaseSearchParameter;
import org.mindrive.system.parameter.system.PasswordParameter;
import org.mindrive.system.parameter.system.UserParameter;
import org.mindrive.system.parameter.system.UsersSearchParameter;
import org.mindrive.system.service.BaseService;
import org.mindrive.system.service.system.RoleService;
import org.mindrive.system.service.system.UserService;

import java.util.List;
import java.util.Map;

import org.mindrive.system.annotation.LogOperation;
import org.mindrive.system.web.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import com.alibaba.fastjson.JSON;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

@Api(tags = { "用户管理" })
@RestController
@RequestMapping("/users")
@Slf4j
public class UserController extends BaseController {

	@Autowired
	private UserService userService;

	@Autowired
	private RoleService roleService;

	@LogOperation(type = BaseService.AUDIT_EVENT_TYPE_SEARCH, event = "查询用户列表")
	@ApiOperation(value = "查询用户列表", notes = "查询用户列表")
	@ApiImplicitParam(name = "authorization", value = "令牌", required = true, paramType = "header")
	@PostMapping(path = "/search")
	public Result search(@RequestBody UsersSearchParameter parameter) {
		log.info("查询用户列表开始。");
		Result result = new Result();
		try {
			Map<String, Object> data = userService.search(parameter);
			result = Result.ok(data);
		} catch (Exception ex) {
			log.error("查询用户列表失败。", ex);
			result = Result.error(ex.getMessage());
		}
		log.info("查询用户列表结束。");
		return result;
	}

	@LogOperation(type = BaseService.AUDIT_EVENT_TYPE_CREATE, event = "新建用户")
	@ApiOperation(value = "新建用户", notes = "新建用户")
	@ApiImplicitParam(name = "authorization", value = "令牌", required = true, paramType = "header")
	@PostMapping(path = "/create")
	public Result create(@Validated @RequestBody UserParameter parameter, BindingResult bindingResult) {
		log.info("新建用户开始。");
		Result result = new Result();
		try {
			validParams(bindingResult);
			UserEntity data = userService.create(parameter);
			result = Result.ok(data);
		} catch (Exception ex) {
			log.error("新建用户失败。", ex);
			result = Result.error(ex.getMessage());
		}
		log.info("新建用户结束。");
		return result;
	}

	@LogOperation(type = BaseService.AUDIT_EVENT_TYPE_MODIFY, event = "修改用户")
	@ApiOperation(value = "修改用户", notes = "修改用户")
	@ApiImplicitParam(name = "authorization", value = "令牌", required = true, paramType = "header")
	@PutMapping(path = "/{id}")
	public Result modify(@PathVariable(value = "id") String id, @Validated @RequestBody UserParameter parameter,
						 BindingResult bindingResult) {
		log.info("修改用户开始。");
		Result result = new Result();
		try {
			validParams(bindingResult);
			userService.modify(id, parameter);
			result = Result.ok();
		} catch (Exception ex) {
			log.error("修改用户失败。", ex);
			result = Result.error(ex.getMessage());
		}
		log.info("修改用户结束。");
		return result;
	}

	@LogOperation(type = BaseService.AUDIT_EVENT_TYPE_DELETE, event = "删除用户")
	@ApiOperation(value = "删除用户", notes = "删除用户")
	@ApiImplicitParam(name = "authorization", value = "令牌", required = true, paramType = "header")
	@PostMapping(path = "/delete")
	public Result delete(@RequestBody List<String> ids) {
		log.info("删除用户开始。");
		Result result = new Result();
		try {
			userService.delete(ids);
			result = Result.ok();
		} catch (Exception ex) {
			log.error("删除用户失败。", ex);
			result = Result.error(ex.getMessage());
		}
		log.info("删除用户结束。");
		return result;
	}

	@LogOperation(type = BaseService.AUDIT_EVENT_TYPE_SEARCH, event = "取得登录用户")
	@ApiOperation(value = "取得登录用户", notes = "取得登录用户")
	@ApiImplicitParam(name = "authorization", value = "令牌", required = true, paramType = "header")
	@GetMapping(path = "/login-user")
	public Result getLoginUser() {
		log.info("取得登录用户开始。");
		Result result = new Result();
		try {
			Map<String, Object> data = userService.getLoginUserInfo();
			result = Result.ok(data);
		} catch (Exception ex) {
			log.error("取得登录用户失败。", ex);
			result = Result.error(ex.getMessage());
		}
		log.info("取得登录用户结束。");
		return result;
	}

	@LogOperation(type = BaseService.AUDIT_EVENT_TYPE_MODIFY, event = "登录用户修改密码")
	@ApiOperation(value = "登录用户修改密码", notes = "登录用户修改密码")
	@ApiImplicitParam(name = "authorization", value = "令牌", required = true, paramType = "header")
	@PostMapping(path = "/modify-password")
	public Result modifyPassword(@Validated @RequestBody PasswordParameter parameter, BindingResult bindingResult) {
		log.info("登录用户修改密码开始。");
		Result result = new Result();
		try {
			validParams(bindingResult);
			userService.modifyPassword(parameter);
			result = Result.ok();
		} catch (Exception ex) {
			log.error("登录用户修改密码失败。", ex);
			result = Result.error(ex.getMessage());
		}
		log.info("登录用户修改密码结束。");
		return result;
	}

	@LogOperation(type = BaseService.AUDIT_EVENT_TYPE_MODIFY, event = "重置用户密码")
	@ApiOperation(value = "重置用户密码", notes = "重置用户密码")
	@ApiImplicitParam(name = "authorization", value = "令牌", required = true, paramType = "header")
	@GetMapping(path = "/reset-password/{id}")
	public Result resetPassword(@PathVariable(value = "id") String id) {
		log.info("重置用户密码开始。");
		Result result = new Result();
		try {
			userService.resetPassword(id);
			result = Result.ok();
		} catch (Exception ex) {
			log.error("重置用户密码失败。", ex);
			result = Result.error(ex.getMessage());
		}
		log.info("重置用户密码结束。");
		return result;
	}

	@LogOperation(type = BaseService.AUDIT_EVENT_TYPE_DELETE, event = "设置用户头像")
	@ApiOperation(value = "设置用户头像", notes = "设置用户头像")
	@ApiImplicitParam(name = "authorization", value = "令牌", required = true, paramType = "header")
	@PostMapping(path = "/set-avatar/{id}")
	public Result setAvatar(@PathVariable(value = "id") String id, @RequestParam("file") MultipartFile avatar) {
		log.info("设置用户头像开始。");
		Result result = new Result();
		try {
			userService.setAvatar(id, avatar);
			result = Result.ok();
		} catch (Exception ex) {
			log.error("设置用户头像失败。", ex);
			result = Result.error(ex.getMessage());
		}
		log.info("设置用户头像结束。");
		return result;
	}



	@LogOperation(type = BaseService.AUDIT_EVENT_TYPE_SEARCH, event = "取得用户角色")
	@ApiOperation(value = "取得用户角色", notes = "取得用户角色")
	@ApiImplicitParam(name = "authorization", value = "令牌", required = true, paramType = "header")
	@GetMapping(path = "/roles/{id}")
	public Result getUserRoleIds(@PathVariable(value = "id") String id) {
		log.info("取得用户角色开始。");
		Result result = new Result();
		try {
			List<String> roleIds = roleService.getRolesForUser(id);
			result = Result.ok(roleIds);
		} catch (Exception ex) {
			log.error("取得用户角色失败。", ex);
			result = Result.error(ex.getMessage());
		}
		log.info("取得用户角色结束。");
		return result;
	}

	@LogOperation(type = BaseService.AUDIT_EVENT_TYPE_MODIFY, event = "设置用户角色")
	@ApiOperation(value = "设置用户角色", notes = "设置用户角色")
	@ApiImplicitParam(name = "authorization", value = "令牌", required = true, paramType = "header")
	@PostMapping(path = "/roles/{id}")
	public Result setUserRoleIds(@PathVariable(value = "id") String id, @RequestBody List<String> roleIds) {
		log.info("设置用户角色开始。");
		Result result = new Result();
		try {
			roleService.setUserRoles(id, roleIds, "");
			result = Result.ok();
		} catch (Exception ex) {
			log.error("设置用户角色失败。", ex);
			result = Result.error(ex.getMessage());
		}
		log.info("设置用户角色结束。");
		return result;
	}

	@LogOperation(type = BaseService.AUDIT_EVENT_TYPE_MODIFY, event = "成员停用")
	@ApiOperation(value = "成员停用", notes = "成员停用")
	@ApiImplicitParam(name = "authorization", value = "令牌", required = true, paramType = "header")
	@PostMapping(path = "/deactive")
	public Result deactive(@RequestBody List<String> userIds) {
		log.info("成员停用开始。[{}]", JSON.toJSONString(userIds));
		Result result = new Result();
		try {
			userService.deactive(userIds);
			result = Result.ok();
		} catch (Exception ex) {
			log.error("成员停用失败。", ex);
			result = Result.error(ex.getMessage());
		}
		log.info("成员停用结束。");
		return result;
	}

	@LogOperation(type = BaseService.AUDIT_EVENT_TYPE_MODIFY, event = "成员启用")
	@ApiOperation(value = "成员启用", notes = "成员启用")
	@ApiImplicitParam(name = "authorization", value = "令牌", required = true, paramType = "header")
	@PostMapping(path = "/active")
	public Result active(@RequestBody List<String> userIds) {
		log.info("成员启用开始。[{}]", JSON.toJSONString(userIds));
		Result result = new Result();
		try {
			userService.active(userIds);
			result = Result.ok();
		} catch (Exception ex) {
			log.error("成员启用失败。", ex);
			result = Result.error(ex.getMessage());
		}
		log.info("成员启用结束。");
		return result;
	}
}
